/**
  CNOK project, Anyang Normal University, IMP-CAS
  \class TAIntegrate
  \brief This class implements general numerical integration. Note that this is
  a mathematical tool class.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2020/07/08
  \date Last modified: 2020/07/22 by SUN Yazhou
  \copyright 2020-2023 SUN Yazhou
  \copyright CNOK project, Anyang Normal University, IMP-CAS
*/

#ifndef _TAIntegrate_h_
#define _TAIntegrate_h_

#include <functional> // use function wrapper to reduce template specifications
#include "TAException.h"

using std::function;

// T: function return type; T: function parameter type
template <typename T1 = double, typename T = double>
class TAIntegrate{
public:
  TAIntegrate(){}
  virtual ~TAIntegrate(){}

  /// computes integration of f over grid x with n points
  static T1 Simpson(int n, const T *x, const T1 *f);
  static T1 Trapezoid(const function<T1(T)> &fun, T a, T b, double eps = 1.e-4);
  static T1 Simpson(const function<T1(T)> &fun, T a, T b, double eps = 1.e-4);
  static T1 Romberg(const function<T1(T)> &fun, T a, T b, double eps = 1.e-4);
  static T1 Romberg(int n, const T *x, const T1 *f, double eps = 1.e-4); ///< f(x) is interpolated
protected:
  /// n-stage quadrature of fun over [a,b]. step: h=(b-a)/2^(n-1).
  /// n starts from 0. This method is defined protected, for it's a underlying
  /// method, only supposed to be used incrementally as
  ///  for(i=0;i<m;i++) s=trapzd(fun, a, b, i)
  static T1 trapzd(const function<T1(T)> &fun, T a, T b, int n);
};

#include "TAIntegrate.hpp" // definitions of member template functions

#endif
